gdk/toplevel: Make gdk_toplevel_present() async
authorJonas Ådahl <jadahl@gmail.com>
Fri, 20 Nov 2020 15:56:36 +0000 (16:56 +0100)
committerJonas Ådahl <jadahl@gmail.com>
Mon, 7 Dec 2020 08:46:39 +0000 (09:46 +0100)
The plan is to concencrate size computations as part of the frame clock
dispatch, meaning we shouldn't do it synchronously in the present()
function.

Still, in Wayland, and maybe elsewhere, it is done in the present()
function, e.g. when no state change was made, but this will eventually
be changed.

gdk/broadway/gdksurface-broadway.c
gdk/gdktoplevel.c
gdk/gdktoplevel.h
gdk/gdktoplevelprivate.h
gdk/wayland/gdksurface-wayland.c
gdk/x11/gdksurface-x11.c

index d9e45ad077226338a7e58f0d35cf3f0f25bdc436..bc5f3eb6c919748bd810493e07271008cf12faed 100644 (file)
@@ -1524,7 +1524,7 @@ show_surface (GdkSurface *surface)
     gdk_surface_invalidate_rect (surface, NULL);
 }
 
-static gboolean
+static void
 gdk_broadway_toplevel_present (GdkToplevel       *toplevel,
                                GdkToplevelLayout *layout)
 {
@@ -1583,8 +1583,6 @@ gdk_broadway_toplevel_present (GdkToplevel       *toplevel,
     gdk_broadway_surface_unmaximize (surface);
 
   show_surface (surface);
-
-  return TRUE;
 }
 
 static gboolean
index 34328db10df350f14910c42e0a3a83bde8ae7888..4cff2bb3dd7bb66d4b9e9095e36c3fa5498f8472 100644 (file)
@@ -51,11 +51,10 @@ enum
 
 static guint signals[N_SIGNALS] = { 0 };
 
-static gboolean
+static void
 gdk_toplevel_default_present (GdkToplevel       *toplevel,
                               GdkToplevelLayout *layout)
 {
-  return FALSE;
 }
 
 static gboolean
@@ -239,18 +238,17 @@ gdk_toplevel_install_properties (GObjectClass *object_class,
  * compute the preferred size of the toplevel surface. See
  * #GdkToplevel::compute-size for details.
  *
- * Presenting may fail.
- *
- * Returns: %FALSE if @toplevel failed to be presented, otherwise %TRUE.
+ * Presenting is asynchronous and the specified layout parameters are not
+ * guaranteed to be respected.
  */
-gboolean
+void
 gdk_toplevel_present (GdkToplevel       *toplevel,
                       GdkToplevelLayout *layout)
 {
-  g_return_val_if_fail (GDK_IS_TOPLEVEL (toplevel), FALSE);
-  g_return_val_if_fail (layout != NULL, FALSE);
+  g_return_if_fail (GDK_IS_TOPLEVEL (toplevel));
+  g_return_if_fail (layout != NULL);
 
-  return GDK_TOPLEVEL_GET_IFACE (toplevel)->present (toplevel, layout);
+  GDK_TOPLEVEL_GET_IFACE (toplevel)->present (toplevel, layout);
 }
 
 /**
index 05fafa4b5f9a8ef9c8dbd42247bd53eb7d15ef74..28402feb105b0b8fabd7a22efe38a47fb4f0cad3 100644 (file)
@@ -129,7 +129,7 @@ GDK_AVAILABLE_IN_ALL
 G_DECLARE_INTERFACE (GdkToplevel, gdk_toplevel, GDK, TOPLEVEL, GObject)
 
 GDK_AVAILABLE_IN_ALL
-gboolean        gdk_toplevel_present            (GdkToplevel       *toplevel,
+void            gdk_toplevel_present            (GdkToplevel       *toplevel,
                                                  GdkToplevelLayout *layout);
 
 GDK_AVAILABLE_IN_ALL
index 989ac29c461506ad0f60f01218e75c9787887c5a..52dcdca0adf767e098a2550a6a93da09bad0bc7f 100644 (file)
@@ -13,7 +13,7 @@ struct _GdkToplevelInterface
 {
   GTypeInterface g_iface;
 
-  gboolean      (* present)             (GdkToplevel       *toplevel,
+  void          (* present)             (GdkToplevel       *toplevel,
                                          GdkToplevelLayout *layout);
   gboolean      (* minimize)            (GdkToplevel       *toplevel);
   gboolean      (* lower)               (GdkToplevel       *toplevel);
index 1c6c27c1c0e8ce2d4b75ddb6af1f4493ec2d6376..27eb433a583b6de5e6137f560888b0b922b42029 100644 (file)
@@ -4756,79 +4756,87 @@ gdk_wayland_toplevel_class_init (GdkWaylandToplevelClass *class)
   gdk_toplevel_install_properties (object_class, 1);
 }
 
-static void
-reconfigure_callback (void               *data,
-                      struct wl_callback *callback,
-                      uint32_t            time)
+static gboolean
+did_maximize_layout_change (GdkToplevel       *toplevel,
+                            GdkToplevelLayout *layout)
 {
-  gboolean *done = (gboolean *) data;
+  GdkSurface *surface = GDK_SURFACE (toplevel);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
 
-  *done = TRUE;
-}
+  if (!impl->toplevel.layout)
+    return TRUE;
 
-static const struct wl_callback_listener reconfigure_listener = {
-  reconfigure_callback
-};
+  if (gdk_toplevel_layout_get_maximized (impl->toplevel.layout) !=
+      gdk_toplevel_layout_get_maximized (layout))
+    return TRUE;
+
+  return FALSE;
+}
 
 static gboolean
+did_fullscreen_layout_change (GdkToplevel       *toplevel,
+                              GdkToplevelLayout *layout)
+{
+  GdkSurface *surface = GDK_SURFACE (toplevel);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
+
+  if (!impl->toplevel.layout)
+    return TRUE;
+
+  if (gdk_toplevel_layout_get_fullscreen (impl->toplevel.layout) !=
+      gdk_toplevel_layout_get_fullscreen (layout))
+    return TRUE;
+
+  if (gdk_toplevel_layout_get_fullscreen_monitor (impl->toplevel.layout) !=
+      gdk_toplevel_layout_get_fullscreen_monitor (layout))
+    return TRUE;
+
+  return FALSE;
+}
+
+static void
 gdk_wayland_toplevel_present (GdkToplevel       *toplevel,
                               GdkToplevelLayout *layout)
 {
   GdkSurface *surface = GDK_SURFACE (toplevel);
   GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
-  GdkWaylandDisplay *display_wayland;
-  struct wl_callback *callback;
-  gboolean done = FALSE;
-  int last_configure_serial = impl->last_configure_serial;
-  gboolean needs_reconfigure = TRUE;
+  gboolean pending_configure = FALSE;
 
-  if (gdk_toplevel_layout_get_maximized (layout))
-    {
-      gdk_wayland_surface_maximize (surface);
-      needs_reconfigure = FALSE;
-    }
-  else
+  if (did_maximize_layout_change (toplevel, layout))
     {
-      gdk_wayland_surface_unmaximize (surface);
+      if (gdk_toplevel_layout_get_maximized (layout))
+        gdk_wayland_surface_maximize (surface);
+      else
+        gdk_wayland_surface_unmaximize (surface);
+      pending_configure = TRUE;
     }
 
-  if (gdk_toplevel_layout_get_fullscreen (layout))
+  if (did_fullscreen_layout_change (toplevel, layout))
     {
-      GdkMonitor *monitor = gdk_toplevel_layout_get_fullscreen_monitor (layout);
-      if (monitor)
-        gdk_wayland_surface_fullscreen_on_monitor (surface, monitor);
+      if (gdk_toplevel_layout_get_fullscreen (layout))
+        {
+          GdkMonitor *monitor;
+
+          monitor = gdk_toplevel_layout_get_fullscreen_monitor (layout);
+          if (monitor)
+            gdk_wayland_surface_fullscreen_on_monitor (surface, monitor);
+          else
+            gdk_wayland_surface_fullscreen (surface);
+        }
       else
-        gdk_wayland_surface_fullscreen (surface);
-      needs_reconfigure = FALSE;
+        {
+          gdk_wayland_surface_unfullscreen (surface);
+        }
+      pending_configure = TRUE;
     }
-  else
-    gdk_wayland_surface_unfullscreen (surface);
 
   g_clear_pointer (&impl->toplevel.layout, gdk_toplevel_layout_unref);
   impl->toplevel.layout = gdk_toplevel_layout_copy (layout);
 
   gdk_wayland_surface_show (surface, FALSE);
 
-  display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
-  callback = wl_display_sync (display_wayland->wl_display);
-  wl_proxy_set_queue ((struct wl_proxy *) callback, impl->event_queue);
-  wl_callback_add_listener (callback,
-                            &reconfigure_listener,
-                            &done);
-  while (is_realized_toplevel (impl) &&
-         (!impl->initial_configure_received || !done))
-    wl_display_dispatch_queue (display_wayland->wl_display, impl->event_queue);
-
-  wl_callback_destroy (callback);
-
-  if (needs_reconfigure &&
-      last_configure_serial == impl->last_configure_serial &&
-      !(surface->state & (GDK_TOPLEVEL_STATE_MAXIMIZED |
-                          GDK_TOPLEVEL_STATE_FULLSCREEN |
-                          GDK_TOPLEVEL_STATE_TILED)))
+  if (!pending_configure)
     configure_surface_geometry (surface);
-
-  return TRUE;
 }
 
 static gboolean
index 24b536cb969e3396c16e0560784d3a2e2c0a0c80..c4b14e11e3f350891352dc5ed74db132bb3add41 100644 (file)
@@ -4849,7 +4849,7 @@ gdk_x11_toplevel_class_init (GdkX11ToplevelClass *class)
   gdk_toplevel_install_properties (object_class, LAST_PROP);
 }
 
-static gboolean
+static void
 gdk_x11_toplevel_present (GdkToplevel       *toplevel,
                           GdkToplevelLayout *layout)
 {
@@ -4922,7 +4922,7 @@ gdk_x11_toplevel_present (GdkToplevel       *toplevel,
     gdk_x11_surface_unfullscreen (surface);
 
   if (surface->destroyed)
-    return TRUE;
+    return;
 
   was_mapped = GDK_SURFACE_IS_MAPPED (surface);
 
@@ -4933,8 +4933,6 @@ gdk_x11_toplevel_present (GdkToplevel       *toplevel,
 
   if (!was_mapped)
     gdk_surface_invalidate_rect (surface, NULL);
-
-  return TRUE;
 }
 
 static gboolean